package com.ztesoft.web.checkup.service.impl;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.ztesoft.core.idproduce.ISequenceGenerator;
import com.ztesoft.framework.log.ZTEsoftLogManager;
import com.ztesoft.framework.util.DateUtils;
import com.ztesoft.framework.util.Utils;
import com.ztesoft.web.baseconfig.db.po.DmPlanPO;
import com.ztesoft.web.baseconfig.db.po.DmStrategyPO;
import com.ztesoft.web.checkup.service.CheckUpFileTaskService;
import com.ztesoft.web.common.DMSConstant;
import com.ztesoft.web.common.Util;
import com.ztesoft.web.common.customdb.dao.dto.DmTaskStageDto;
import com.ztesoft.web.common.db.dao.DmHostConnInfoDao;
import com.ztesoft.web.common.db.po.DmHostConnInfoPO;
import com.ztesoft.web.common.vo.HostConnInfoVO;
import com.ztesoft.web.common.vo.HostConnMethodVO;
import com.ztesoft.web.common.vo.HostInfoPOJO;
import com.ztesoft.web.filecommon.customdb.dao.DmFCustomDao;
import com.ztesoft.web.filecommon.db.dao.DmFDao;
import com.ztesoft.web.filecommon.db.dao.DmFDetailDao;
import com.ztesoft.web.filecommon.db.po.DmFDetailPO;
import com.ztesoft.web.filecommon.db.po.DmFPO;
import com.ztesoft.web.filecommon.db.po.DmSrcFilePO;
import com.ztesoft.web.syncbaseinfo.service.BaseInfoService;

/**
 * 文件体检处理
 */
@Service("CheckUpFileTaskServiceImpl")
public class CheckUpFileTaskServiceImpl implements CheckUpFileTaskService {
	
	private static final ZTEsoftLogManager LOGGER = ZTEsoftLogManager.getLogger(CheckUpFileTaskServiceImpl.class);
	
	@Resource(name="sequenceProcGenerator")
	private ISequenceGenerator sequenceGenerator;

	@Autowired
	private DmFDao dmfDao;
	
	@Autowired
	private DmHostConnInfoDao  dmHostConnInfoDao;
	
	@Autowired
	private DmFDetailDao dmFDetailDao;
	
	@Autowired
	private DmFCustomDao dmFCustomDao;
	
	@Autowired
	private BaseInfoService baseInfoService;
	
	@Override
	public void addCheckUp(String state, DmStrategyPO strategyPO, 
			int taskId, DmSrcFilePO dmSrcFilePO, DmTaskStageDto taskStagePO, DmPlanPO dmPlanPO) throws Exception{
		//1、首先，使用策略ID组出DM_F_#策略ID#表名，然后提取其数据
		String tableName = "DM_F_"+strategyPO.getDmStrategyId();
		List<DmFPO> dfList = dmfDao.selectDmFByDmInfoId(tableName, taskStagePO.getDmInfoId());
		Map<String, List<DmFPO>> map = new HashMap<String, List<DmFPO>>();
		Map<String, HostConnMethodVO> connMethodMap = null;// 主机连接信息
		
		//2、从取得的记录中得到源主机IP、执行脚本等，连接源主机，在源主机上执行体检脚本
		//    主机分组
		for (DmFPO dmFPO : dfList) {
			String key = dmFPO.getSrcIp()+"-"+dmFPO.getSrcUser();
			if(map.containsKey(key)){
				map.get(key).add(dmFPO);
			}else{
				List<DmFPO> dfpList = new ArrayList<DmFPO>();
				dfpList.add(dmFPO);
				map.put(key, dfpList);
			}
		}
		connMethodMap = new HashMap<String, HostConnMethodVO>();
		for (Map.Entry<String, List<DmFPO>> entry : map.entrySet()) {  
			 String ip = entry.getKey().split("-")[0];
			 DmHostConnInfoPO dhci = dmHostConnInfoDao.selectBySrcIp(ip);
			 HostConnInfoVO hostConnInfoVO;
			try {
				hostConnInfoVO = baseInfoService.queryHostConn(dhci.getHostId());
				 List<HostConnMethodVO> hostConnMethodList = hostConnInfoVO.getHostConnMethod();
				 for (HostConnMethodVO vo : hostConnMethodList) {
						connMethodMap.put(vo.getConnMethod().toLowerCase(), vo);
				}
				 HostConnMethodVO vo =  connMethodMap.get(DMSConstant.HOST_LINK_SSH);
				 HostInfoPOJO hostInfoPOJO = new HostInfoPOJO(dhci.getOsType(), dhci.getIp(), 
						 vo.getUserName(), vo.getPassword(), vo.getPort(), true);
				 List<DmFPO> dfpList = entry.getValue();
				 String checkRes = "";
				 String count = "0";
				 for (DmFPO dmFPO : dfpList) {
					 dmFCustomDao.updatedmfStateByTrackId(strategyPO.getDmStrategyId(), dmFPO.getTrackId(), "00R");
					 List<DmFDetailPO> dmFList = new ArrayList<DmFDetailPO>();
					 //Find “源目录”  “搜索规则”  |wc –l 
					 String countStr =  dmFPO.getShellScript() + " |wc -l";
					 if("0".equals(getMapByExecShell((Map<String, String>) Util.execShellBySSHMethod(hostInfoPOJO, countStr).get(0)))){
						continue; 
					 }
					 List<Object> resultLists = Util.execShellBySSHMethod(hostInfoPOJO, 
							 dmFPO.getShellScript() + " |wc -l", dmFPO.getShellScript() + " |xargs ls -l |awk '{print$5,$9}'");
					 String shellCount = "0";
					 List<String> resList = null;
					 if(Utils.notEmpty(resultLists)){
						 shellCount = getMapByExecShell((Map<String, String>) resultLists.get(0));
						 checkRes = getMapByExecShell((Map<String, String>) resultLists.get(1));
						 if(Utils.notEmpty(shellCount)){
							 count = Utils.convertIdString2ListByComma(shellCount).get(0);
						 }
						 if(Utils.notEmpty(checkRes)&&!count.equals("0")){
							 resList = Utils.convertIdString2ListByComma(checkRes);
						 }
					 }
					 // 写入体检结果明细表
					 Integer dmStrategyId = dmFPO.getDmStrategyId();
					 String tableDetailName = "dm_f_detail_" + dmStrategyId;
					 int pkId;
					 if(Utils.notEmpty(resList)){
						 for (String res : resList) {
							List<String> conveList = Utils.convertIdString2ListByComma(res," ");
							DmFDetailPO dfdPO = new DmFDetailPO();
							pkId = sequenceGenerator.sequenceIntValue("DM_F_DETAIL", "DETAIL_ID");
							dfdPO.setDetailId(pkId);
							dfdPO.setTrackId(dmFPO.getTrackId());
							dfdPO.setDmTaskId(dmFPO.getDmTaskId());
							dfdPO.setAbsolutePath(conveList.get(1));
							dfdPO.setFileType("");
							dfdPO.setFilesize(new BigDecimal(conveList.get(0).trim()).divide(BigDecimal.valueOf(1024)));
							dfdPO.setFilename(conveList.get(1));
							dfdPO.setFilesCount(count);
							dfdPO.setState(setStateByOperType(dmPlanPO.getOperType()));
							dfdPO.setStateDate(new Date());
							dmFList.add(dfdPO);
							}
						 dmFDetailDao.insertBatch(tableDetailName, dmFList);
						 //5.更新备份任务环节表状态
						 BigDecimal size = dmFDetailDao.selectByTrackId( dmFPO.getTrackId(), dmFPO.getDmStrategyId()).getFilesize();
						 dmFPO.setState("00T");
						 dmFPO.setStateDate(DateUtils.getDBCurrentTime());
						 dmFPO.setTotalRecordCount(Integer.valueOf(count));
						 dmFPO.setCheckDataCount(Integer.valueOf(count));
						 dmFPO.setTotalRecordSize(size);
						 dmFPO.setCheckDataSize(size);
						 dmfDao.updateByArgSelectiveSize(tableName, dmFPO, dmFPO.getTrackId());//
					 }
					 /*2.1、	若执行成功，则将体检结果文件明细记录写入DM_F_#策略ID#表，写入完成后，
					更新DM_TASK_STAGE表中的结果数据量(即文件总数)、体检总数据量(即体检结果文件总数)、
					体检结果数据大小(即文件总大小)、体检总数据大小(即体检结果文件总大小)及记录状态(更新为00A)。*/
				}
			} catch (Exception e) {
				LOGGER.error("|体检异常|",e);
			}
		}
		//5.更新备份任务环节表状态
		taskStagePO.setTaskStartTime(DateUtils.getDBCurrentTime());
		taskStagePO.setStateDate(DateUtils.getDBCurrentTime());
		DmFPO dmfpo = dmfDao.selectTotalRecord(tableName, taskStagePO.getDmInfoId());
		if(Utils.notEmpty(dmfpo)){
			taskStagePO.setCheckCount(dmfpo.getCheckDataCount());
			taskStagePO.setCheckDataSize(dmfpo.getCheckDataSize());
			taskStagePO.setTotalRecordCount(dmfpo.getTotalRecordCount());
			taskStagePO.setTotalDataSize(dmfpo.getTotalRecordSize());
		}else{
			taskStagePO.setCheckCount(0);
			taskStagePO.setCheckDataSize(BigDecimal.ZERO);
			taskStagePO.setTotalRecordCount(0);
			taskStagePO.setTotalDataSize(BigDecimal.ZERO);
		}
		taskStagePO.setCheckState(DMSConstant.SUCCESS);
	}
	
	private String getMapByExecShell(Map<String, String> resultMap){
		 String retStr = "";
		 String resultStr = resultMap.get("SUC");
		 String errStr = resultMap.get("ERR");
		 if(Utils.notEmpty(resultStr)){
			 retStr = resultStr.substring(0, resultStr.length()-1);
		 }
		 if(Utils.notEmpty(errStr)){
			 LOGGER.debug("执行shell脚本异常："+errStr);
		 }
		 return retStr;
	}
	private String setStateByOperType(int operType){
		String state = "00A";
		if(0==operType){
			state = "00B";
		}else if(1==operType){
			state = "00C";
		}
		return state;
		
	}
}
